package com.weilele.mvvm.utils.thread

import androidx.lifecycle.LifecycleOwner
import com.weilele.mvvm.base.helper.ILifecycleObserver
import com.weilele.mvvm.mainHandler

/**
 * 自动循环任务
 * [TickTask]内部是用协程实现，效果更好
 */
@Deprecated("请使用[TickTask]", ReplaceWith("TickTask"))
class LoopTask(private val runnable: LoopTask.() -> Unit, private val time: Long) :
    Runnable, ILifecycleObserver {
    companion object {
        /**
         * 启动轮询
         */
        fun start(time: Long = 1000L, run: LoopTask.() -> Unit): LoopTask {
            return LoopTask(run, time).also {
                it.run()
            }
        }

        /**
         * 带有生命周期的启动
         */
        fun startWithLifecycleOwner(
            owner: LifecycleOwner,
            time: Long = 1000L,
            run: LoopTask.() -> Unit
        ): LoopTask {
            val task = start(time, run)
            owner.lifecycle.addObserver(task)
            return task
        }

        /**
         * 停止轮询
         */
        fun LoopTask.stop() {
            cancel()
        }
    }

    /**
     * 当生命周期补不可见的时候，是否任务仍在运行
     */
    private var isRunningWhenStop = false

    /**
     * 是否已经取消
     */
    private var isCanceled = true

    /**
     * 任务是否正在运行中
     */
    val isRunning: Boolean
        get() = !isCanceled

    /**
     * run
     */
    override fun run() {
        isCanceled = false
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q
            && mainHandler.hasCallbacks(this)
        ) {
            return
        }
        mainHandler.postDelayed(this, time)
        runnable.invoke(this)
    }

    /**
     * 取消回调
     */
    fun cancel() {
        mainHandler.removeCallbacks(this)
        isCanceled = true
        isRunningWhenStop = false
    }

    override fun onStart() {
        super.onStart()
        //如果取消的时候正在运行，则自动恢复
        if (isRunningWhenStop) {
            run()
        }
    }

    override fun onStop() {
        super.onStop()
        //必须在cancel前赋值
        val runningWhenStop = !isCanceled
        cancel()
        //必须在cancel后赋值
        isRunningWhenStop = runningWhenStop
    }
}
